package com.cong.common.util.aspect;

import com.alibaba.fastjson.JSON;
import com.cong.common.vo.AjaxResultVo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.stream.Collectors;

@Aspect
@Component
public class ControllerLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(ControllerLogAspect.class);

    // 定义切点，匹配所有 @Controller 注解的类及其方法
    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void controllerPointcut() {}

    // 在方法执行前拦截，打印入参
    @Before("controllerPointcut()")
    public void logBefore(JoinPoint joinPoint) {
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();

        // 打印参数类型
        String argTypes = Arrays.stream(args)
                .map(arg -> arg != null ? arg.getClass().getSimpleName() : "null")
                .collect(Collectors.joining(", "));

        logger.info("Controller 方法调用: {}.{} 入参类型: [{}]", className, methodName, argTypes);
        logger.info("Controller 方法调用: {}.{} 入参: {}", className, methodName, Arrays.toString(args));
    }

    // 在方法执行后拦截，打印返回值
    @AfterReturning(pointcut = "controllerPointcut()", returning = "result")
    public void logAfter(JoinPoint joinPoint, Object result) {
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        String resultStr;
        if (result instanceof AjaxResultVo) {
            resultStr = JSON.toJSONString(result); // 正确调用静态方法
        } else {
            resultStr = result != null ? result.toString() : "null";
        }
        resultStr= resultStr.length()>500?resultStr.substring(0,500)+"......":resultStr;
        logger.info("Controller 方法返回: {}.{} 返回值: {}", className, methodName, resultStr);
    }
}